<?php
#
# dmBridge: a data access framework for CONTENTdm(R)
#
# Copyright © 2009, 2010, 2011 Board of Regents of the Nevada System of Higher
# Education, on behalf of the University of Nevada, Las Vegas
#

/**
 * @author Alex Dolski <alex.dolski@unlv.edu>
 * @license http://www.opensource.org/licenses/mit-license.php
 */

$dmloadstart = microtime(true); // used to calculate response time

require_once(dirname(__FILE__) . "/autoload.php");

// if the path ends with a slash, 301 redirect to trimmed version
$uri = DMHTTPRequest::getCurrent()->getURI();
if (substr($uri->getPath(), -1, 1) == "/") {
	// avoid circular web server redirect to trailing slash
	if (strlen(rtrim($uri->getPath(), "/")) > strlen(dirname($_SERVER['PHP_SELF']))) {
		header("HTTP/1.1 301 Moved Permanently");
		header("Location: " . rtrim($uri->getPath(), "/"));
		die;
	}
}

// Bootstrap all modules before the session is started so that all class
// definitions have been loaded before any objects that may potentially use
// them have been deserialized.
DMModuleManager::getInstance()->bootstrapAllModules();

if ($uri->isControlPanel()) {
	session_name("dmBridge_session");
	session_cache_limiter("private, no-cache, must-revalidate");
	session_start();
} else if ($uri->isTemplateEngine()) {
	session_name("dmBridge_session");
	session_cache_limiter("public, max-age=86400"); // expire after 1 day
	session_start();
}

unset($uri);

/* PHP error messages are HTML-encoded, which is not going to work when we're
 * serving non-HTML content. By converting all messages into exceptions, we
 * can handle them our own way instead of having PHP emit them, invalidating
 * our XML/JSON. It would be nice to convert all error levels, but
 * DMSystem.php generates some E_NOTICEs in the course of its normal
 * operation. */
set_error_handler("dmErrorHandler", E_ALL ^ E_NOTICE);

function dmErrorHandler($errno, $errstr, $errfile, $errline) {
	// http://us.php.net/manual/en/class.errorexception.php
	try {
		throw new DMErrorException($errstr, $errno);
	} catch (ErrorException $e) {
		bailOut($e);
	}
}

try {
	// Will be accessible in the HTML templates. Controllers will declare this
	// a global and assign it a reference to the current DMInternalView object.
	$view = null;

	$route = DMHTTPRequest::getCurrent()->getURI()->getRoute();
	if ($route instanceof DMRoute && $route->isValid()) {
		$ctrlr = $route->getController();
		$ctrlr = new $ctrlr;
		$method = $route->getMethod();

		$components = DMHTTPRequest::getCurrent()->getURI()->getParamComponents();
		if ($components[0] == "objects") {
			// initialize the template set
			$alias = "/dmdefault";
			if (count($components) > 1 && !in_array($components[1],
							array("login", "logout", "favorites", "search"))) {
				$alias = DMCollection::getSanitizedAlias("/" . $components[1]);
			}
			$col = null;
			if (DMCollection::exists($alias)) {
				$col = DMCollectionFactory::getCollection($alias);
				if ($col->isUsingDefaultTemplateSet()) {
					$col = DMCollectionFactory::getCollection("/dmdefault");

				}
				$ts = $col->getTemplateSet();
			} else {
				$col = DMCollectionFactory::getCollection("/dmdefault");
				$ts = $col->getTemplateSet();
			}
			$ctrlr->setTemplateSet($ts);
		}
		if (method_exists($ctrlr, $method)) {
			$ctrlr->$method($route->getParameters());
		}
	} else {
		throw new DMInvalidRouteException();
	}

	if ($view) {
		$tpl_path = $view->getTemplate()->getAbsolutePathname();
		if (!file_exists($tpl_path)) {
			throw new DMUnavailableModelException(
				sprintf(DMLocalizedString::getString("INVALID_ROUTE_VIEW"),
					$tpl_path));
		}

		include_once($tpl_path);
	}
} catch (Exception $e) {
	bailOut($e);
}

function bailOut(Exception $e) {
	$components = DMHTTPRequest::getCurrent()->getURI()->getParamComponents();
	if ($components[0] == "api") {
		$response = new DMHTTPResponse();
		$rep = DMHTTPResponseFactory::getRepresentation();
		$trans = DMHTTPResponseFactory::getTransformer();
		if ($trans) {
			if ($trans instanceof DMXMLRepresentationTransformer) {
				$trans->setPrettyPrint(true);
			}
			$rep->setBody($trans->transformException($e));
		} else {
			$rep->setBody($e->getMessage());
		}
		$response->setRepresentation($rep);
		if (method_exists($e, "getHTTPResponseCode")) {
			$response->setStatusCode($e->getHTTPResponseCode());
		}
		$response->send();
		die;
	} else {
		$ts = new DMTemplateSet();
		$ts->setPath(dirname($_SERVER['PHP_SELF']) . "/templates/system");
		$path = "/error.html.php";
		$tpl = new DMTemplate($ts, $path);
		$view = new DMSystemErrorView($tpl,
				DMHTTPRequest::getCurrent()->getSession(), $e);
		require_once($tpl->getAbsolutePathname());
		die;
	}

}
